(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Neo4jd3 = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
        'use strict';

        var neo4jd3 = _dereq_('./scripts/neo4jd3');

        module.exports = neo4jd3;

    },{"./scripts/neo4jd3":2}],2:[function(_dereq_,module,exports){
        /* global d3, document */
        /* jshint latedef:nofunc */
        'use strict';

        function Neo4jD3(_selector, _options) {
            var container, graph, info, node, nodes, relationship, relationshipOutline, relationshipOverlay, relationshipText, relationships, selector, simulation, svg, svgNodes, svgRelationships, svgScale, svgTranslate,
                classes2colors = {},
                justLoaded = false,
                numClasses = 0,
                options = {
                    arrowSize: 4,
                    colors: colors(),
                    highlight: undefined,
                    iconMap: fontAwesomeIcons(),
                    icons: undefined,
                    imageMap: {},
                    images: undefined,
                    infoPanel: true,
                    minCollision: undefined,
                    neo4jData: undefined,
                    neo4jDataUrl: undefined,
                    nodeOutlineFillColor: undefined,
                    nodeRadius: 25,
                    relationshipColor: '#a5abb6',
                    zoomFit: false
                },
                VERSION = '0.0.1';

            function appendGraph(container) {
                svg = container.append('svg')
                    .attr('width', '100%')
                    .attr('height', '100%')
                    .attr('class', 'neo4jd3-graph')
                    .call(d3.zoom().on('zoom', function() {
                        var scale = d3.event.transform.k,
                            translate = [d3.event.transform.x, d3.event.transform.y];

                        if (svgTranslate) {
                            translate[0] += svgTranslate[0];
                            translate[1] += svgTranslate[1];
                        }

                        if (svgScale) {
                            scale *= svgScale;
                        }

                        svg.attr('transform', 'translate(' + translate[0] + ', ' + translate[1] + ') scale(' + scale + ')');
                    }))
                    .on('dblclick.zoom', null)
                    .append('g')
                    .attr('width', '100%')
                    .attr('height', '100%');

                svgRelationships = svg.append('g')
                    .attr('class', 'relationships');

                svgNodes = svg.append('g')
                    .attr('class', 'nodes');
            }

            function appendImageToNode(node) {
                return node.append('image')
                    .attr('height', function(d) {
                        return icon(d) ? '24px': '30px';
                    })
                    .attr('x', function(d) {
                        return icon(d) ? '5px': '-15px';
                    })
                    .attr('xlink:href', function(d) {
                        return image(d);
                    })
                    .attr('y', function(d) {
                        return icon(d) ? '5px': '-16px';
                    })
                    .attr('width', function(d) {
                        return icon(d) ? '24px': '30px';
                    });
            }

            //下面这个代码用于向节点添加名称
            function appendNameToNode(node) {
                // let
                return node.append('text')
                    .attr('font-size', '14px')
                    .attr('text-anchor', 'middle')
                    // .attr('x', function(d) {
                    //     return icon(d) ? '-20px': '0';
                    // })
                    .attr('y', function(d) {
                        return icon(d) ? '50px': '16px';
                    })
                    .html(function(d) {
                        var _icon = icon(d);
                        // return _icon ? '&#x' + _icon : d.id;
                        return d.properties['name']
                    })

            }

            function appendInfoPanel(container) {
                return container.append('div')
                    .attr('class', 'neo4jd3-info');
            }

            function appendInfoElement(cls, isNode, property, value) {
                var elem = info.append('a');

                elem.attr('href', '#')
                    .attr('class', cls)
                    .html('<strong>' + property + '</strong>' + (value ? (': ' + value) : ''));

                if (!value) {
                    elem.style('background-color', function(d) {
                        return options.nodeOutlineFillColor ? options.nodeOutlineFillColor : (isNode ? class2color(property) : defaultColor());
                    })
                        .style('border-color', function(d) {
                            return options.nodeOutlineFillColor ? class2darkenColor(options.nodeOutlineFillColor) : (isNode ? class2darkenColor(property) : defaultDarkenColor());
                        })
                        .style('color', function(d) {
                            return options.nodeOutlineFillColor ? class2darkenColor(options.nodeOutlineFillColor) : '#fff';
                        });
                }
            }

            function appendInfoElementClass(cls, node) {
                appendInfoElement(cls, true, node);
            }

            function appendInfoElementProperty(cls, property, value) {
                appendInfoElement(cls, false, property, value);
            }

            function appendInfoElementRelationship(cls, relationship) {
                appendInfoElement(cls, false, relationship);
            }

            function appendNode() {
                return node.enter()
                    .append('g')
                    .attr('class', function(d) {
                        var highlight, i,
                            classes = 'node',
                            label = d.labels[0];

                        if (icon(d)) {
                            classes += ' node-icon';
                        }

                        if (image(d)) {
                            classes += ' node-image';
                        }

                        if (options.highlight) {
                            for (i = 0; i < options.highlight.length; i++) {
                                highlight = options.highlight[i];

                                if (d.labels[0] === highlight.class && d.properties[highlight.property] === highlight.value) {
                                    classes += ' node-highlighted';
                                    break;
                                }
                            }
                        }

                        return classes;
                    })
                    .on('click', function(d) {
                        d.fx = d.fy = null;

                        if (typeof options.onNodeClick === 'function') {
                            options.onNodeClick(d);
                        }
                    })
                    .on('dblclick', function(d) {
                        stickNode(d);
                        console.log("dblclick");
                        if (typeof options.onNodeDoubleClick === 'function') {
                            options.onNodeDoubleClick(d);
                        }
                    })
                    .on('mouseenter', function(d) {
                        if (info) {
                            updateInfo(d);
                        }

                        if (typeof options.onNodeMouseEnter === 'function') {
                            options.onNodeMouseEnter(d);
                        }
                    })
                    .on('mouseleave', function(d) {
                        if (info) {
                            clearInfo(d);
                        }

                        if (typeof options.onNodeMouseLeave === 'function') {
                            options.onNodeMouseLeave(d);
                        }
                    })
                    .call(d3.drag()
                        .on('start', dragStarted)
                        .on('drag', dragged)
                        .on('end', dragEnded));
            }

            function appendNodeToGraph() {
                var n = appendNode();

                appendRingToNode(n);
                appendOutlineToNode(n);
                appendNameToNode(n);   //此处尝试向ring外添加名称

                if (options.icons) {
                    appendTextToNode(n);
                }

                if (options.images) {
                    appendImageToNode(n);
                }

                return n;
            }


            function appendOutlineToNode(node) {
                return node.append('circle')
                    .attr('class', 'outline')
                    .attr('r', options.nodeRadius)
                    .style('fill', function(d) {
                        return options.nodeOutlineFillColor ? options.nodeOutlineFillColor : class2color(d.labels[0]);
                    })
                    .style('stroke', function(d) {
                        return options.nodeOutlineFillColor ? class2darkenColor(options.nodeOutlineFillColor) : class2darkenColor(d.labels[0]);
                    })
                    .append('title').text(function(d) {
                        return toString(d);
                    });
            }

            function appendRingToNode(node) {
                return node.append('circle')
                    .attr('class', 'ring')
                    .attr('r', options.nodeRadius * 1.16)
                    .append('p').text(function(d) { //此处进行修改 title换为p
                        // return toString(d);
                        return d.properties['name']   //此处进行修改 返回title为节点的名称
                    });
            }

            function appendTextToNode(node) {
                return node.append('text')
                    .attr('class', function(d) {
                        return 'text' + (icon(d) ? ' icon' : '');
                    })
                    .attr('fill', '#ffffff')
                    .attr('font-size', function(d) {
                        return icon(d) ? (options.nodeRadius + 'px') : '10px';
                    })
                    .attr('pointer-events', 'none')
                    .attr('text-anchor', 'middle')
                    .attr('y', function(d) {
                        return icon(d) ? (parseInt(Math.round(options.nodeRadius * 0.32)) + 'px') : '4px';
                    })
                    .html(function(d) {
                        var _icon = icon(d);
                        return _icon ? '&#x' + _icon : d.id;
                        // return d.properties['name']
                    });
            }

            function appendRandomDataToNode(d, maxNodesToGenerate) {
                var data = randomD3Data(d, maxNodesToGenerate);
                updateWithNeo4jData(data);
            }

            function appendRelationship() {
                return relationship.enter()
                    .append('g')
                    .attr('class', 'relationship')
                    .on('dblclick', function(d) {
                        if (typeof options.onRelationshipDoubleClick === 'function') {
                            options.onRelationshipDoubleClick(d);
                        }
                    })
                    .on('mouseenter', function(d) {
                        if (info) {
                            updateInfo(d);
                        }
                    });
            }

            function appendOutlineToRelationship(r) {
                return r.append('path')
                    .attr('class', 'outline')
                    .attr('fill', '#a5abb6')
                    .attr('stroke', 'none');
            }

            function appendOverlayToRelationship(r) {
                return r.append('path')
                    .attr('class', 'overlay');
            }

            function appendTextToRelationship(r) {
                return r.append('text')
                    .attr('class', 'text')
                    .attr('fill', '#000000')
                    .attr('font-size', '8px')
                    .attr('pointer-events', 'none')
                    .attr('text-anchor', 'middle')
                    .text(function(d) {
                        return d.type;
                    });
            }

            function appendRelationshipToGraph() {
                var relationship = appendRelationship(),
                    text = appendTextToRelationship(relationship),
                    outline = appendOutlineToRelationship(relationship),
                    overlay = appendOverlayToRelationship(relationship);

                return {
                    outline: outline,
                    overlay: overlay,
                    relationship: relationship,
                    text: text
                };
            }

            function class2color(cls) {
                var color = classes2colors[cls];

                if (!color) {
//            color = options.colors[Math.min(numClasses, options.colors.length - 1)];
                    color = options.colors[numClasses % options.colors.length];
                    classes2colors[cls] = color;
                    numClasses++;
                }

                return color;
            }

            function class2darkenColor(cls) {
                return d3.rgb(class2color(cls)).darker(1);
            }

            function clearInfo() {
                info.html('');
            }

            function color() {
                return options.colors[options.colors.length * Math.random() << 0];
            }

            function colors() {
                // d3.schemeCategory10,
                // d3.schemeCategory20,
                return [
                    '#68bdf6', // light blue
                    '#6dce9e', // green #1
                    '#faafc2', // light pink
                    '#f2baf6', // purple
                    '#ff928c', // light red
                    '#fcea7e', // light yellow
                    '#ffc766', // light orange
                    '#405f9e', // navy blue
                    '#a5abb6', // dark gray
                    '#78cecb', // green #2,
                    '#b88cbb', // dark purple
                    '#ced2d9', // light gray
                    '#e84646', // dark red
                    '#fa5f86', // dark pink
                    '#ffab1a', // dark orange
                    '#fcda19', // dark yellow
                    '#797b80', // black
                    '#c9d96f', // pistacchio
                    '#47991f', // green #3
                    '#70edee', // turquoise
                    '#ff75ea'  // pink
                ];
            }

            function contains(array, id) {
                var filter = array.filter(function(elem) {
                    return elem.id === id;
                });

                return filter.length > 0;
            }

            function defaultColor() {
                return options.relationshipColor;
            }

            function defaultDarkenColor() {
                return d3.rgb(options.colors[options.colors.length - 1]).darker(1);
            }

            function dragEnded(d) {
                if (!d3.event.active) {
                    simulation.alphaTarget(0);
                }

                if (typeof options.onNodeDragEnd === 'function') {
                    options.onNodeDragEnd(d);
                }
            }

            function dragged(d) {
                stickNode(d);
                console.log("dragged");
            }

            function dragStarted(d) {
                if (!d3.event.active) {
                    simulation.alphaTarget(0.3).restart();
                }

                d.fx = d.x;
                d.fy = d.y;

                if (typeof options.onNodeDragStart === 'function') {
                    options.onNodeDragStart(d);
                }
            }

            function extend(obj1, obj2) {
                var obj = {};

                merge(obj, obj1);
                merge(obj, obj2);

                return obj;
            }

            function fontAwesomeIcons() {
                return {'glass':'f000','music':'f001','search':'f002','envelope-o':'f003','heart':'f004','star':'f005','star-o':'f006','user':'f007','film':'f008','th-large':'f009','th':'f00a','th-list':'f00b','check':'f00c','remove,close,times':'f00d','search-plus':'f00e','search-minus':'f010','power-off':'f011','signal':'f012','gear,cog':'f013','trash-o':'f014','home':'f015','file-o':'f016','clock-o':'f017','road':'f018','download':'f019','arrow-circle-o-down':'f01a','arrow-circle-o-up':'f01b','inbox':'f01c','play-circle-o':'f01d','rotate-right,repeat':'f01e','refresh':'f021','list-alt':'f022','lock':'f023','flag':'f024','headphones':'f025','volume-off':'f026','volume-down':'f027','volume-up':'f028','qrcode':'f029','barcode':'f02a','tag':'f02b','tags':'f02c','book':'f02d','bookmark':'f02e','print':'f02f','camera':'f030','font':'f031','bold':'f032','italic':'f033','text-height':'f034','text-width':'f035','align-left':'f036','align-center':'f037','align-right':'f038','align-justify':'f039','list':'f03a','dedent,outdent':'f03b','indent':'f03c','video-camera':'f03d','photo,image,picture-o':'f03e','pencil':'f040','map-marker':'f041','adjust':'f042','tint':'f043','edit,pencil-square-o':'f044','share-square-o':'f045','check-square-o':'f046','arrows':'f047','step-backward':'f048','fast-backward':'f049','backward':'f04a','play':'f04b','pause':'f04c','stop':'f04d','forward':'f04e','fast-forward':'f050','step-forward':'f051','eject':'f052','chevron-left':'f053','chevron-right':'f054','plus-circle':'f055','minus-circle':'f056','times-circle':'f057','check-circle':'f058','question-circle':'f059','info-circle':'f05a','crosshairs':'f05b','times-circle-o':'f05c','check-circle-o':'f05d','ban':'f05e','arrow-left':'f060','arrow-right':'f061','arrow-up':'f062','arrow-down':'f063','mail-forward,share':'f064','expand':'f065','compress':'f066','plus':'f067','minus':'f068','asterisk':'f069','exclamation-circle':'f06a','gift':'f06b','leaf':'f06c','fire':'f06d','eye':'f06e','eye-slash':'f070','warning,exclamation-triangle':'f071','plane':'f072','calendar':'f073','random':'f074','comment':'f075','magnet':'f076','chevron-up':'f077','chevron-down':'f078','retweet':'f079','shopping-cart':'f07a','folder':'f07b','folder-open':'f07c','arrows-v':'f07d','arrows-h':'f07e','bar-chart-o,bar-chart':'f080','twitter-square':'f081','facebook-square':'f082','camera-retro':'f083','key':'f084','gears,cogs':'f085','comments':'f086','thumbs-o-up':'f087','thumbs-o-down':'f088','star-half':'f089','heart-o':'f08a','sign-out':'f08b','linkedin-square':'f08c','thumb-tack':'f08d','external-link':'f08e','sign-in':'f090','trophy':'f091','github-square':'f092','upload':'f093','lemon-o':'f094','phone':'f095','square-o':'f096','bookmark-o':'f097','phone-square':'f098','twitter':'f099','facebook-f,facebook':'f09a','github':'f09b','unlock':'f09c','credit-card':'f09d','feed,rss':'f09e','hdd-o':'f0a0','bullhorn':'f0a1','bell':'f0f3','certificate':'f0a3','hand-o-right':'f0a4','hand-o-left':'f0a5','hand-o-up':'f0a6','hand-o-down':'f0a7','arrow-circle-left':'f0a8','arrow-circle-right':'f0a9','arrow-circle-up':'f0aa','arrow-circle-down':'f0ab','globe':'f0ac','wrench':'f0ad','tasks':'f0ae','filter':'f0b0','briefcase':'f0b1','arrows-alt':'f0b2','group,users':'f0c0','chain,link':'f0c1','cloud':'f0c2','flask':'f0c3','cut,scissors':'f0c4','copy,files-o':'f0c5','paperclip':'f0c6','save,floppy-o':'f0c7','square':'f0c8','navicon,reorder,bars':'f0c9','list-ul':'f0ca','list-ol':'f0cb','strikethrough':'f0cc','underline':'f0cd','table':'f0ce','magic':'f0d0','truck':'f0d1','pinterest':'f0d2','pinterest-square':'f0d3','google-plus-square':'f0d4','google-plus':'f0d5','money':'f0d6','caret-down':'f0d7','caret-up':'f0d8','caret-left':'f0d9','caret-right':'f0da','columns':'f0db','unsorted,sort':'f0dc','sort-down,sort-desc':'f0dd','sort-up,sort-asc':'f0de','envelope':'f0e0','linkedin':'f0e1','rotate-left,undo':'f0e2','legal,gavel':'f0e3','dashboard,tachometer':'f0e4','comment-o':'f0e5','comments-o':'f0e6','flash,bolt':'f0e7','sitemap':'f0e8','umbrella':'f0e9','paste,clipboard':'f0ea','lightbulb-o':'f0eb','exchange':'f0ec','cloud-download':'f0ed','cloud-upload':'f0ee','user-md':'f0f0','stethoscope':'f0f1','suitcase':'f0f2','bell-o':'f0a2','coffee':'f0f4','cutlery':'f0f5','file-text-o':'f0f6','building-o':'f0f7','hospital-o':'f0f8','ambulance':'f0f9','medkit':'f0fa','fighter-jet':'f0fb','beer':'f0fc','h-square':'f0fd','plus-square':'f0fe','angle-double-left':'f100','angle-double-right':'f101','angle-double-up':'f102','angle-double-down':'f103','angle-left':'f104','angle-right':'f105','angle-up':'f106','angle-down':'f107','desktop':'f108','laptop':'f109','tablet':'f10a','mobile-phone,mobile':'f10b','circle-o':'f10c','quote-left':'f10d','quote-right':'f10e','spinner':'f110','circle':'f111','mail-reply,reply':'f112','github-alt':'f113','folder-o':'f114','folder-open-o':'f115','smile-o':'f118','frown-o':'f119','meh-o':'f11a','gamepad':'f11b','keyboard-o':'f11c','flag-o':'f11d','flag-checkered':'f11e','terminal':'f120','code':'f121','mail-reply-all,reply-all':'f122','star-half-empty,star-half-full,star-half-o':'f123','location-arrow':'f124','crop':'f125','code-fork':'f126','unlink,chain-broken':'f127','question':'f128','info':'f129','exclamation':'f12a','superscript':'f12b','subscript':'f12c','eraser':'f12d','puzzle-piece':'f12e','microphone':'f130','microphone-slash':'f131','shield':'f132','calendar-o':'f133','fire-extinguisher':'f134','rocket':'f135','maxcdn':'f136','chevron-circle-left':'f137','chevron-circle-right':'f138','chevron-circle-up':'f139','chevron-circle-down':'f13a','html5':'f13b','css3':'f13c','anchor':'f13d','unlock-alt':'f13e','bullseye':'f140','ellipsis-h':'f141','ellipsis-v':'f142','rss-square':'f143','play-circle':'f144','ticket':'f145','minus-square':'f146','minus-square-o':'f147','level-up':'f148','level-down':'f149','check-square':'f14a','pencil-square':'f14b','external-link-square':'f14c','share-square':'f14d','compass':'f14e','toggle-down,caret-square-o-down':'f150','toggle-up,caret-square-o-up':'f151','toggle-right,caret-square-o-right':'f152','euro,eur':'f153','gbp':'f154','dollar,usd':'f155','rupee,inr':'f156','cny,rmb,yen,jpy':'f157','ruble,rouble,rub':'f158','won,krw':'f159','bitcoin,btc':'f15a','file':'f15b','file-text':'f15c','sort-alpha-asc':'f15d','sort-alpha-desc':'f15e','sort-amount-asc':'f160','sort-amount-desc':'f161','sort-numeric-asc':'f162','sort-numeric-desc':'f163','thumbs-up':'f164','thumbs-down':'f165','youtube-square':'f166','youtube':'f167','xing':'f168','xing-square':'f169','youtube-play':'f16a','dropbox':'f16b','stack-overflow':'f16c','instagram':'f16d','flickr':'f16e','adn':'f170','bitbucket':'f171','bitbucket-square':'f172','tumblr':'f173','tumblr-square':'f174','long-arrow-down':'f175','long-arrow-up':'f176','long-arrow-left':'f177','long-arrow-right':'f178','apple':'f179','windows':'f17a','android':'f17b','linux':'f17c','dribbble':'f17d','skype':'f17e','foursquare':'f180','trello':'f181','female':'f182','male':'f183','gittip,gratipay':'f184','sun-o':'f185','moon-o':'f186','archive':'f187','bug':'f188','vk':'f189','weibo':'f18a','renren':'f18b','pagelines':'f18c','stack-exchange':'f18d','arrow-circle-o-right':'f18e','arrow-circle-o-left':'f190','toggle-left,caret-square-o-left':'f191','dot-circle-o':'f192','wheelchair':'f193','vimeo-square':'f194','turkish-lira,try':'f195','plus-square-o':'f196','space-shuttle':'f197','slack':'f198','envelope-square':'f199','wordpress':'f19a','openid':'f19b','institution,bank,university':'f19c','mortar-board,graduation-cap':'f19d','yahoo':'f19e','google':'f1a0','reddit':'f1a1','reddit-square':'f1a2','stumbleupon-circle':'f1a3','stumbleupon':'f1a4','delicious':'f1a5','digg':'f1a6','pied-piper-pp':'f1a7','pied-piper-alt':'f1a8','drupal':'f1a9','joomla':'f1aa','language':'f1ab','fax':'f1ac','building':'f1ad','child':'f1ae','paw':'f1b0','spoon':'f1b1','cube':'f1b2','cubes':'f1b3','behance':'f1b4','behance-square':'f1b5','steam':'f1b6','steam-square':'f1b7','recycle':'f1b8','automobile,car':'f1b9','cab,taxi':'f1ba','tree':'f1bb','spotify':'f1bc','deviantart':'f1bd','soundcloud':'f1be','database':'f1c0','file-pdf-o':'f1c1','file-word-o':'f1c2','file-excel-o':'f1c3','file-powerpoint-o':'f1c4','file-photo-o,file-picture-o,file-image-o':'f1c5','file-zip-o,file-archive-o':'f1c6','file-sound-o,file-audio-o':'f1c7','file-movie-o,file-video-o':'f1c8','file-code-o':'f1c9','vine':'f1ca','codepen':'f1cb','jsfiddle':'f1cc','life-bouy,life-buoy,life-saver,support,life-ring':'f1cd','circle-o-notch':'f1ce','ra,resistance,rebel':'f1d0','ge,empire':'f1d1','git-square':'f1d2','git':'f1d3','y-combinator-square,yc-square,hacker-news':'f1d4','tencent-weibo':'f1d5','qq':'f1d6','wechat,weixin':'f1d7','send,paper-plane':'f1d8','send-o,paper-plane-o':'f1d9','history':'f1da','circle-thin':'f1db','header':'f1dc','paragraph':'f1dd','sliders':'f1de','share-alt':'f1e0','share-alt-square':'f1e1','bomb':'f1e2','soccer-ball-o,futbol-o':'f1e3','tty':'f1e4','binoculars':'f1e5','plug':'f1e6','slideshare':'f1e7','twitch':'f1e8','yelp':'f1e9','newspaper-o':'f1ea','wifi':'f1eb','calculator':'f1ec','paypal':'f1ed','google-wallet':'f1ee','cc-visa':'f1f0','cc-mastercard':'f1f1','cc-discover':'f1f2','cc-amex':'f1f3','cc-paypal':'f1f4','cc-stripe':'f1f5','bell-slash':'f1f6','bell-slash-o':'f1f7','trash':'f1f8','copyright':'f1f9','at':'f1fa','eyedropper':'f1fb','paint-brush':'f1fc','birthday-cake':'f1fd','area-chart':'f1fe','pie-chart':'f200','line-chart':'f201','lastfm':'f202','lastfm-square':'f203','toggle-off':'f204','toggle-on':'f205','bicycle':'f206','bus':'f207','ioxhost':'f208','angellist':'f209','cc':'f20a','shekel,sheqel,ils':'f20b','meanpath':'f20c','buysellads':'f20d','connectdevelop':'f20e','dashcube':'f210','forumbee':'f211','leanpub':'f212','sellsy':'f213','shirtsinbulk':'f214','simplybuilt':'f215','skyatlas':'f216','cart-plus':'f217','cart-arrow-down':'f218','diamond':'f219','ship':'f21a','user-secret':'f21b','motorcycle':'f21c','street-view':'f21d','heartbeat':'f21e','venus':'f221','mars':'f222','mercury':'f223','intersex,transgender':'f224','transgender-alt':'f225','venus-double':'f226','mars-double':'f227','venus-mars':'f228','mars-stroke':'f229','mars-stroke-v':'f22a','mars-stroke-h':'f22b','neuter':'f22c','genderless':'f22d','facebook-official':'f230','pinterest-p':'f231','whatsapp':'f232','server':'f233','user-plus':'f234','user-times':'f235','hotel,bed':'f236','viacoin':'f237','train':'f238','subway':'f239','medium':'f23a','yc,y-combinator':'f23b','optin-monster':'f23c','opencart':'f23d','expeditedssl':'f23e','battery-4,battery-full':'f240','battery-3,battery-three-quarters':'f241','battery-2,battery-half':'f242','battery-1,battery-quarter':'f243','battery-0,battery-empty':'f244','mouse-pointer':'f245','i-cursor':'f246','object-group':'f247','object-ungroup':'f248','sticky-note':'f249','sticky-note-o':'f24a','cc-jcb':'f24b','cc-diners-club':'f24c','clone':'f24d','balance-scale':'f24e','hourglass-o':'f250','hourglass-1,hourglass-start':'f251','hourglass-2,hourglass-half':'f252','hourglass-3,hourglass-end':'f253','hourglass':'f254','hand-grab-o,hand-rock-o':'f255','hand-stop-o,hand-paper-o':'f256','hand-scissors-o':'f257','hand-lizard-o':'f258','hand-spock-o':'f259','hand-pointer-o':'f25a','hand-peace-o':'f25b','trademark':'f25c','registered':'f25d','creative-commons':'f25e','gg':'f260','gg-circle':'f261','tripadvisor':'f262','odnoklassniki':'f263','odnoklassniki-square':'f264','get-pocket':'f265','wikipedia-w':'f266','safari':'f267','chrome':'f268','firefox':'f269','opera':'f26a','internet-explorer':'f26b','tv,television':'f26c','contao':'f26d','500px':'f26e','amazon':'f270','calendar-plus-o':'f271','calendar-minus-o':'f272','calendar-times-o':'f273','calendar-check-o':'f274','industry':'f275','map-pin':'f276','map-signs':'f277','map-o':'f278','map':'f279','commenting':'f27a','commenting-o':'f27b','houzz':'f27c','vimeo':'f27d','black-tie':'f27e','fonticons':'f280','reddit-alien':'f281','edge':'f282','credit-card-alt':'f283','codiepie':'f284','modx':'f285','fort-awesome':'f286','usb':'f287','product-hunt':'f288','mixcloud':'f289','scribd':'f28a','pause-circle':'f28b','pause-circle-o':'f28c','stop-circle':'f28d','stop-circle-o':'f28e','shopping-bag':'f290','shopping-basket':'f291','hashtag':'f292','bluetooth':'f293','bluetooth-b':'f294','percent':'f295','gitlab':'f296','wpbeginner':'f297','wpforms':'f298','envira':'f299','universal-access':'f29a','wheelchair-alt':'f29b','question-circle-o':'f29c','blind':'f29d','audio-description':'f29e','volume-control-phone':'f2a0','braille':'f2a1','assistive-listening-systems':'f2a2','asl-interpreting,american-sign-language-interpreting':'f2a3','deafness,hard-of-hearing,deaf':'f2a4','glide':'f2a5','glide-g':'f2a6','signing,sign-language':'f2a7','low-vision':'f2a8','viadeo':'f2a9','viadeo-square':'f2aa','snapchat':'f2ab','snapchat-ghost':'f2ac','snapchat-square':'f2ad','pied-piper':'f2ae','first-order':'f2b0','yoast':'f2b1','themeisle':'f2b2','google-plus-circle,google-plus-official':'f2b3','fa,font-awesome':'f2b4'};
            }

            function icon(d) {
                var code;

                if (options.iconMap && options.showIcons && options.icons) {
                    if (options.icons[d.labels[0]] && options.iconMap[options.icons[d.labels[0]]]) {
                        code = options.iconMap[options.icons[d.labels[0]]];
                    } else if (options.iconMap[d.labels[0]]) {
                        code = options.iconMap[d.labels[0]];
                    } else if (options.icons[d.labels[0]]) {
                        code = options.icons[d.labels[0]];
                    }
                }

                return code;
            }

            function image(d) {
                var i, imagesForLabel, img, imgLevel, label, labelPropertyValue, property, value;

                if (options.images) {
                    imagesForLabel = options.imageMap[d.labels[0]];

                    if (imagesForLabel) {
                        imgLevel = 0;

                        for (i = 0; i < imagesForLabel.length; i++) {
                            labelPropertyValue = imagesForLabel[i].split('|');

                            switch (labelPropertyValue.length) {
                                case 3:
                                    value = labelPropertyValue[2];
                                /* falls through */
                                case 2:
                                    property = labelPropertyValue[1];
                                /* falls through */
                                case 1:
                                    label = labelPropertyValue[0];
                            }

                            if (d.labels[0] === label &&
                                (!property || d.properties[property] !== undefined) &&
                                (!value || d.properties[property] === value)) {
                                if (labelPropertyValue.length > imgLevel) {
                                    img = options.images[imagesForLabel[i]];
                                    imgLevel = labelPropertyValue.length;
                                }
                            }
                        }
                    }
                }

                return img;
            }

            function init(_selector, _options) {
                initIconMap();

                merge(options, _options);

                if (options.icons) {
                    options.showIcons = true;
                }

                if (!options.minCollision) {
                    options.minCollision = options.nodeRadius * 2;
                }

                initImageMap();

                selector = _selector;

                container = d3.select(selector);

                container.attr('class', 'neo4jd3')
                    .html('');

                if (options.infoPanel) {
                    info = appendInfoPanel(container);
                }

                appendGraph(container);

                simulation = initSimulation();

                if (options.neo4jData) {
                    loadNeo4jData(options.neo4jData);
                } else if (options.neo4jDataUrl) {
                    loadNeo4jDataFromUrl(options.neo4jDataUrl);
                } else {
                    console.error('Error: both neo4jData and neo4jDataUrl are empty!');
                }
            }

            function initIconMap() {
                Object.keys(options.iconMap).forEach(function(key, index) {
                    var keys = key.split(','),
                        value = options.iconMap[key];

                    keys.forEach(function(key) {
                        options.iconMap[key] = value;
                    });
                });
            }

            function initImageMap() {
                var key, keys, selector;

                for (key in options.images) {
                    if (options.images.hasOwnProperty(key)) {
                        keys = key.split('|');

                        if (!options.imageMap[keys[0]]) {
                            options.imageMap[keys[0]] = [key];
                        } else {
                            options.imageMap[keys[0]].push(key);
                        }
                    }
                }
            }

            function initSimulation() {
                var simulation = d3.forceSimulation()
                //                           .velocityDecay(0.8)
                //                           .force('x', d3.force().strength(0.002))
                //                           .force('y', d3.force().strength(0.002))
                    .force('collide', d3.forceCollide().radius(function(d) {
                        return options.minCollision;
                    }).iterations(2))
                    .force('charge', d3.forceManyBody())
                    .force('link', d3.forceLink().id(function(d) {
                        return d.id;
                    }))
                    .force('center', d3.forceCenter(svg.node().parentElement.parentElement.clientWidth / 2, svg.node().parentElement.parentElement.clientHeight / 2))
                    .on('tick', function() {
                        tick();
                    })
                    .on('end', function() {
                        if (options.zoomFit && !justLoaded) {
                            justLoaded = true;
                            zoomFit(2);
                        }
                    });

                return simulation;
            }

            function loadNeo4jData() {
                nodes = [];
                relationships = [];

                updateWithNeo4jData(options.neo4jData);
            }

            function loadNeo4jDataFromUrl(neo4jDataUrl) {
                nodes = [];
                relationships = [];

                d3.json(neo4jDataUrl, function(error, data) {
                    if (error) {
                        throw error;
                    }

                    updateWithNeo4jData(data);
                });
            }

            function merge(target, source) {
                Object.keys(source).forEach(function(property) {
                    target[property] = source[property];
                });
            }

            function neo4jDataToD3Data(data) {
                var graph = {
                    nodes: [],
                    relationships: []
                };

                data.results.forEach(function(result) {
                    result.data.forEach(function(data) {
                        data.graph.nodes.forEach(function(node) {
                            if (!contains(graph.nodes, node.id)) {
                                graph.nodes.push(node);
                            }
                        });

                        data.graph.relationships.forEach(function(relationship) {
                            relationship.source = relationship.startNode;
                            relationship.target = relationship.endNode;
                            graph.relationships.push(relationship);
                        });

                        data.graph.relationships.sort(function(a, b) {
                            if (a.source > b.source) {
                                return 1;
                            } else if (a.source < b.source) {
                                return -1;
                            } else {
                                if (a.target > b.target) {
                                    return 1;
                                }

                                if (a.target < b.target) {
                                    return -1;
                                } else {
                                    return 0;
                                }
                            }
                        });

                        for (var i = 0; i < data.graph.relationships.length; i++) {
                            if (i !== 0 && data.graph.relationships[i].source === data.graph.relationships[i-1].source && data.graph.relationships[i].target === data.graph.relationships[i-1].target) {
                                data.graph.relationships[i].linknum = data.graph.relationships[i - 1].linknum + 1;
                            } else {
                                data.graph.relationships[i].linknum = 1;
                            }
                        }
                    });
                });

                return graph;
            }

            function randomD3Data(d, maxNodesToGenerate) {
                var data = {
                        nodes: [],
                        relationships: []
                    },
                    i,
                    label,
                    node,
                    numNodes = (maxNodesToGenerate * Math.random() << 0) + 1,
                    relationship,
                    s = size();

                for (i = 0; i < numNodes; i++) {
                    label = randomLabel();

                    node = {
                        id: s.nodes + 1 + i,
                        labels: [label],
                        properties: {
                            random: label
                        },
                        x: d.x,
                        y: d.y
                    };

                    data.nodes[data.nodes.length] = node;

                    relationship = {
                        id: s.relationships + 1 + i,
                        type: label.toUpperCase(),
                        startNode: d.id,
                        endNode: s.nodes + 1 + i,
                        properties: {
                            from: Date.now()
                        },
                        source: d.id,
                        target: s.nodes + 1 + i,
                        linknum: s.relationships + 1 + i
                    };

                    data.relationships[data.relationships.length] = relationship;
                }

                return data;
            }

            function randomLabel() {
                var icons = Object.keys(options.iconMap);
                return icons[icons.length * Math.random() << 0];
            }

            function rotate(cx, cy, x, y, angle) {
                var radians = (Math.PI / 180) * angle,
                    cos = Math.cos(radians),
                    sin = Math.sin(radians),
                    nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
                    ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;

                return { x: nx, y: ny };
            }

            function rotatePoint(c, p, angle) {
                return rotate(c.x, c.y, p.x, p.y, angle);
            }

            function rotation(source, target) {
                return Math.atan2(target.y - source.y, target.x - source.x) * 180 / Math.PI;
            }

            function size() {
                return {
                    nodes: nodes.length,
                    relationships: relationships.length
                };
            }
            /*
                function smoothTransform(elem, translate, scale) {
                    var animationMilliseconds = 5000,
                        timeoutMilliseconds = 50,
                        steps = parseInt(animationMilliseconds / timeoutMilliseconds);
                    setTimeout(function() {
                        smoothTransformStep(elem, translate, scale, timeoutMilliseconds, 1, steps);
                    }, timeoutMilliseconds);
                }
                function smoothTransformStep(elem, translate, scale, timeoutMilliseconds, step, steps) {
                    var progress = step / steps;
                    elem.attr('transform', 'translate(' + (translate[0] * progress) + ', ' + (translate[1] * progress) + ') scale(' + (scale * progress) + ')');
                    if (step < steps) {
                        setTimeout(function() {
                            smoothTransformStep(elem, translate, scale, timeoutMilliseconds, step + 1, steps);
                        }, timeoutMilliseconds);
                    }
                }
            */
            function stickNode(d) {
                d.fx = d3.event.x;
                d.fy = d3.event.y;
            }

            function tick() {
                tickNodes();
                tickRelationships();
            }

            function tickNodes() {
                if (node) {
                    node.attr('transform', function(d) {
                        return 'translate(' + d.x + ', ' + d.y + ')';
                    });
                }
            }

            function tickRelationships() {
                if (relationship) {
                    relationship.attr('transform', function(d) {
                        var angle = rotation(d.source, d.target);
                        return 'translate(' + d.source.x + ', ' + d.source.y + ') rotate(' + angle + ')';
                    });

                    tickRelationshipsTexts();
                    tickRelationshipsOutlines();
                    tickRelationshipsOverlays();
                }
            }

            function tickRelationshipsOutlines() {
                relationship.each(function(relationship) {
                    var rel = d3.select(this),
                        outline = rel.select('.outline'),
                        text = rel.select('.text'),
                        bbox = text.node().getBBox(),
                        padding = 3;

                    outline.attr('d', function(d) {
                        var center = { x: 0, y: 0 },
                            angle = rotation(d.source, d.target),
                            textBoundingBox = text.node().getBBox(),
                            textPadding = 5,
                            u = unitaryVector(d.source, d.target),
                            textMargin = { x: (d.target.x - d.source.x - (textBoundingBox.width + textPadding) * u.x) * 0.5, y: (d.target.y - d.source.y - (textBoundingBox.width + textPadding) * u.y) * 0.5 },
                            n = unitaryNormalVector(d.source, d.target),
                            rotatedPointA1 = rotatePoint(center, { x: 0 + (options.nodeRadius + 1) * u.x - n.x, y: 0 + (options.nodeRadius + 1) * u.y - n.y }, angle),
                            rotatedPointB1 = rotatePoint(center, { x: textMargin.x - n.x, y: textMargin.y - n.y }, angle),
                            rotatedPointC1 = rotatePoint(center, { x: textMargin.x, y: textMargin.y }, angle),
                            rotatedPointD1 = rotatePoint(center, { x: 0 + (options.nodeRadius + 1) * u.x, y: 0 + (options.nodeRadius + 1) * u.y }, angle),
                            rotatedPointA2 = rotatePoint(center, { x: d.target.x - d.source.x - textMargin.x - n.x, y: d.target.y - d.source.y - textMargin.y - n.y }, angle),
                            rotatedPointB2 = rotatePoint(center, { x: d.target.x - d.source.x - (options.nodeRadius + 1) * u.x - n.x - u.x * options.arrowSize, y: d.target.y - d.source.y - (options.nodeRadius + 1) * u.y - n.y - u.y * options.arrowSize }, angle),
                            rotatedPointC2 = rotatePoint(center, { x: d.target.x - d.source.x - (options.nodeRadius + 1) * u.x - n.x + (n.x - u.x) * options.arrowSize, y: d.target.y - d.source.y - (options.nodeRadius + 1) * u.y - n.y + (n.y - u.y) * options.arrowSize }, angle),
                            rotatedPointD2 = rotatePoint(center, { x: d.target.x - d.source.x - (options.nodeRadius + 1) * u.x, y: d.target.y - d.source.y - (options.nodeRadius + 1) * u.y }, angle),
                            rotatedPointE2 = rotatePoint(center, { x: d.target.x - d.source.x - (options.nodeRadius + 1) * u.x + (- n.x - u.x) * options.arrowSize, y: d.target.y - d.source.y - (options.nodeRadius + 1) * u.y + (- n.y - u.y) * options.arrowSize }, angle),
                            rotatedPointF2 = rotatePoint(center, { x: d.target.x - d.source.x - (options.nodeRadius + 1) * u.x - u.x * options.arrowSize, y: d.target.y - d.source.y - (options.nodeRadius + 1) * u.y - u.y * options.arrowSize }, angle),
                            rotatedPointG2 = rotatePoint(center, { x: d.target.x - d.source.x - textMargin.x, y: d.target.y - d.source.y - textMargin.y }, angle);

                        return 'M ' + rotatedPointA1.x + ' ' + rotatedPointA1.y +
                            ' L ' + rotatedPointB1.x + ' ' + rotatedPointB1.y +
                            ' L ' + rotatedPointC1.x + ' ' + rotatedPointC1.y +
                            ' L ' + rotatedPointD1.x + ' ' + rotatedPointD1.y +
                            ' Z M ' + rotatedPointA2.x + ' ' + rotatedPointA2.y +
                            ' L ' + rotatedPointB2.x + ' ' + rotatedPointB2.y +
                            ' L ' + rotatedPointC2.x + ' ' + rotatedPointC2.y +
                            ' L ' + rotatedPointD2.x + ' ' + rotatedPointD2.y +
                            ' L ' + rotatedPointE2.x + ' ' + rotatedPointE2.y +
                            ' L ' + rotatedPointF2.x + ' ' + rotatedPointF2.y +
                            ' L ' + rotatedPointG2.x + ' ' + rotatedPointG2.y +
                            ' Z';
                    });
                });
            }

            function tickRelationshipsOverlays() {
                relationshipOverlay.attr('d', function(d) {
                    var center = { x: 0, y: 0 },
                        angle = rotation(d.source, d.target),
                        n1 = unitaryNormalVector(d.source, d.target),
                        n = unitaryNormalVector(d.source, d.target, 50),
                        rotatedPointA = rotatePoint(center, { x: 0 - n.x, y: 0 - n.y }, angle),
                        rotatedPointB = rotatePoint(center, { x: d.target.x - d.source.x - n.x, y: d.target.y - d.source.y - n.y }, angle),
                        rotatedPointC = rotatePoint(center, { x: d.target.x - d.source.x + n.x - n1.x, y: d.target.y - d.source.y + n.y - n1.y }, angle),
                        rotatedPointD = rotatePoint(center, { x: 0 + n.x - n1.x, y: 0 + n.y - n1.y }, angle);

                    return 'M ' + rotatedPointA.x + ' ' + rotatedPointA.y +
                        ' L ' + rotatedPointB.x + ' ' + rotatedPointB.y +
                        ' L ' + rotatedPointC.x + ' ' + rotatedPointC.y +
                        ' L ' + rotatedPointD.x + ' ' + rotatedPointD.y +
                        ' Z';
                });
            }

            function tickRelationshipsTexts() {
                relationshipText.attr('transform', function(d) {
                    var angle = (rotation(d.source, d.target) + 360) % 360,
                        mirror = angle > 90 && angle < 270,
                        center = { x: 0, y: 0 },
                        n = unitaryNormalVector(d.source, d.target),
                        nWeight = mirror ? 2 : -3,
                        point = { x: (d.target.x - d.source.x) * 0.5 + n.x * nWeight, y: (d.target.y - d.source.y) * 0.5 + n.y * nWeight },
                        rotatedPoint = rotatePoint(center, point, angle);

                    return 'translate(' + rotatedPoint.x + ', ' + rotatedPoint.y + ') rotate(' + (mirror ? 180 : 0) + ')';
                });
            }

            function toString(d) {
                var s = d.labels ? d.labels[0] : d.type;

                s += ' (<id>: ' + d.id;

                Object.keys(d.properties).forEach(function(property) {
                    s += ', ' + property + ': ' + JSON.stringify(d.properties[property]);
                });

                s += ')';

                return s;
            }

            function unitaryNormalVector(source, target, newLength) {
                var center = { x: 0, y: 0 },
                    vector = unitaryVector(source, target, newLength);

                return rotatePoint(center, vector, 90);
            }

            function unitaryVector(source, target, newLength) {
                var length = Math.sqrt(Math.pow(target.x - source.x, 2) + Math.pow(target.y - source.y, 2)) / Math.sqrt(newLength || 1);

                return {
                    x: (target.x - source.x) / length,
                    y: (target.y - source.y) / length,
                };
            }

            function updateWithD3Data(d3Data) {
                updateNodesAndRelationships(d3Data.nodes, d3Data.relationships);
            }

            function updateWithNeo4jData(neo4jData) {
                var d3Data = neo4jDataToD3Data(neo4jData);
                updateWithD3Data(d3Data);
            }

            function updateInfo(d) {
                clearInfo();

                if (d.labels) {
                    appendInfoElementClass('class', d.labels[0]);
                } else {
                    appendInfoElementRelationship('class', d.type);
                }

                appendInfoElementProperty('property', '&lt;id&gt;', d.id);

                Object.keys(d.properties).forEach(function(property) {
                    appendInfoElementProperty('property', property, JSON.stringify(d.properties[property]));
                });
            }

            function updateNodes(n) {
                Array.prototype.push.apply(nodes, n);

                node = svgNodes.selectAll('.node')
                    .data(nodes, function(d) { return d.id; });
                var nodeEnter = appendNodeToGraph();
                node = nodeEnter.merge(node);
            }

            function updateNodesAndRelationships(n, r) {
                updateRelationships(r);
                updateNodes(n);

                simulation.nodes(nodes);
                simulation.force('link').links(relationships);
            }

            function updateRelationships(r) {
                Array.prototype.push.apply(relationships, r);

                relationship = svgRelationships.selectAll('.relationship')
                    .data(relationships, function(d) { return d.id; });

                var relationshipEnter = appendRelationshipToGraph();

                relationship = relationshipEnter.relationship.merge(relationship);

                relationshipOutline = svg.selectAll('.relationship .outline');
                relationshipOutline = relationshipEnter.outline.merge(relationshipOutline);

                relationshipOverlay = svg.selectAll('.relationship .overlay');
                relationshipOverlay = relationshipEnter.overlay.merge(relationshipOverlay);

                relationshipText = svg.selectAll('.relationship .text');
                relationshipText = relationshipEnter.text.merge(relationshipText);
            }

            function version() {
                return VERSION;
            }

            function zoomFit(transitionDuration) {
                var bounds = svg.node().getBBox(),
                    parent = svg.node().parentElement.parentElement,
                    fullWidth = parent.clientWidth,
                    fullHeight = parent.clientHeight,
                    width = bounds.width,
                    height = bounds.height,
                    midX = bounds.x + width / 2,
                    midY = bounds.y + height / 2;

                if (width === 0 || height === 0) {
                    return; // nothing to fit
                }

                svgScale = 0.85 / Math.max(width / fullWidth, height / fullHeight);
                svgTranslate = [fullWidth / 2 - svgScale * midX, fullHeight / 2 - svgScale * midY];

                svg.attr('transform', 'translate(' + svgTranslate[0] + ', ' + svgTranslate[1] + ') scale(' + svgScale + ')');
//        smoothTransform(svgTranslate, svgScale);
            }

            init(_selector, _options);

            return {
                appendRandomDataToNode: appendRandomDataToNode,
                neo4jDataToD3Data: neo4jDataToD3Data,
                randomD3Data: randomD3Data,
                size: size,
                updateWithD3Data: updateWithD3Data,
                updateWithNeo4jData: updateWithNeo4jData,
                version: version
            };
        }

        module.exports = Neo4jD3;

    },{}]},{},[1])(1)
});
